﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Autofac;
using Autofac.Extras.DynamicProxy;
using BaseRepository.Db;
using BaseService;
using Extensions.Interceptor.Cache;

namespace Extensions.Services;



public class AddAutoFac : Autofac.Module
{
    private readonly List<Assembly> _registerAssemblys;
    private readonly List<Type> _interceptors;

    public AddAutoFac(List<Assembly> RegisterAssemblyTypes, List<Type> interceptors = null)
    {
        _registerAssemblys = RegisterAssemblyTypes;
        _interceptors = interceptors ?? new List<Type>();
        // 添加两个缓存过滤器 且方在最前面
        _interceptors.InsertRange(0,
            (new Type[]
            {
                typeof(MemoryCacheInterceptor)
            }).ToList());
    }

    // 注入type之后 获取不到assmenbly的信息  直接把string 注入进来  或者注入assembly就好了

    /// <summary>
    /// 添加autofac  只是批量注入service层就好了 仓储层使用原生的ioc进行泛型的注入
    /// </summary>
    /// <param name="builder"></param>
    protected override void Load(ContainerBuilder builder)
    {
        // 如果为null  那么就不注入了
        if (_registerAssemblys == null)
        {
            return;
        }
        // 注册缓存拦截器
        builder.AddCacheInterceptor();
        // 注册一些基础的组件 
        // baseRepository 支持属性注入
        builder.RegisterGeneric(typeof(BaseRepository<>))
            .As(typeof(IBaseRepository<>))
            .InstancePerLifetimeScope()
            .PropertiesAutowired();
        builder.RegisterGeneric(typeof(BaseService<>))
            .As(typeof(IBaseService<>))
            .InstancePerLifetimeScope()
            .PropertiesAutowired();

        // 实现类单独注入  这边可能会使用aop
        foreach (var assembly in _registerAssemblys)
        {
            //var tempBuilder = builder.RegisterAssemblyTypes(assembly);
            // 这边走通过反射来创建
            // 这个方法只注入 service结尾的类  应为 没有使用接口
            if (assembly.FullName.Contains("Domain"))
                builder.RegisterAssemblyTypes(assembly).Where(p => p.FullName.EndsWith("Service"))
                    .AsSelf()
                    .InstancePerLifetimeScope()
                    .PropertiesAutowired()
                    .EnableClassInterceptors()
                    .InterceptedBy(typeof(MemoryCacheInterceptor));

            if (assembly.FullName.Contains("Infrastructure"))
                builder.RegisterAssemblyTypes(assembly)
                    .Where(p=>p.FullName.EndsWith("Repository"))
                    .AsImplementedInterfaces() // 自动使用接口注入
                    .InstancePerLifetimeScope() // 声明周期是scope
                    .PropertiesAutowired()//支持属性注入
                    .EnableInterfaceInterceptors()
                    .InterceptedBy(typeof(MemoryCacheInterceptor)); 

        }
    }
}


